package org.moyrax.nereyda.services.events
{
	import org.moyrax.nereyda.services.factory.EventFactory;
	
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	
	import mx.collections.ArrayCollection;

	/**
	 * Permite manipular eventos vinculados a los servicios.
	 */
	public class ServiceEventDispatcher implements IEventDispatcher
	{
		private static var instance :ServiceEventDispatcher = null;
		private var eventListeners :ArrayCollection = new ArrayCollection();
		
		public static function getInstance():ServiceEventDispatcher
		{
			if ( instance == null )
				instance = new ServiceEventDispatcher();
			
			return( instance );
		}

		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			var _type     :String = type;
			var _listener :Function = listener;
			var _priority :int = priority;
			
			if ( this.listenerExists(type, listener) )
				return;

			this.eventListeners.addItem( {
				type     : _type,
				listener : _listener,
				priority : _priority
			} );
		}
		
		public function addListenerClass(event:Class, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			var _type :String = EventFactory.getInstance().getEventName(event);
			
			this.addEventListener( 
				_type, 
				listener, 
				useCapture, 
				priority, 
				useWeakReference 
			);
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			var listeners :ArrayCollection = this.getListeners(type);
			
			for each ( var event :Object in this.eventListeners ) {
				if ( event.listener == listener ){
					var id:int = eventListeners.getItemIndex( event );
					
					eventListeners.removeItemAt(id);
				}
			}
		}
		
		public function dispatchEvent(event:Event):Boolean
		{
			if ( event == null )
				return(false);
				
			var listeners :ArrayCollection = this.getListeners(event.type);
			
			for each ( var events :Object in listeners ) {
				if ( events.listener( event ) == null )
					return(false); 
			}
			
			return( true );
		}
		
		public function hasEventListener(type:String):Boolean
		{
			var listeners :ArrayCollection = this.getListeners(type);

			return( (listeners.length > 0) );
		}
		
		public function willTrigger(type:String):Boolean
		{
			return( false );
		}
		
		private function getListeners(type:String):ArrayCollection
		{
			var result :ArrayCollection = new ArrayCollection();
			
			for each ( var event:Object in eventListeners ) {
				if ( event.type == type ) {
					result.addItem(event);
				}
			}
			
			return( result );
		}
		
		private function listenerExists( type:String, listener:Function ):Boolean
		{
			for each ( var event:Object in eventListeners ) {
				if ( (event.type == type) ||
				     (event.listener == listener) ) {
					return( true );
				}
			}
			
			return( false );
		}
	}
}